package net.towee.client.com.lobby.view;

import java.util.HashMap;
import java.util.Map;

import net.towee.client.com.lobby.Lobby.Step;
import net.towee.client.com.lobby.presenter.LobbyPresenter.Display;
import net.towee.client.i18n.ToweeConstants;
import net.towee.client.resources.ClientResource;
import net.towee.client.widgets.ListItemWidget;
import net.towee.client.widgets.UnorderedListWidget;

import com.google.gwt.animation.client.Animation;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.inject.Inject;

/**
 * Sexy view of lobby.
 * 
 * @author c58
 */
public class LobbyView extends FlowPanel implements Display, ResizeHandler {
	
	public class StepChangingAnimation extends Animation {
		private int moveSelectLength;
		private int currentSelectLeft;
		
		private int currentStepLeft;
		private int moveStepLength;
		
		@Override
		protected void onUpdate(double progress) {
			selectedButton.getElement().getStyle().setProperty("left", (currentSelectLeft+(progress*moveSelectLength))+"px");
			steps.getElement().getStyle().setProperty("left", ((currentStepLeft+(progress*moveStepLength))*(-1))+"px");
		}

		public void run(int duration, Step toStep) {
			currentSelectLeft = selectedButton.getElement().getAbsoluteLeft();
			moveSelectLength = buttonsMap.get(toStep).getElement().getAbsoluteLeft()-currentSelectLeft;
			
			currentStepLeft = steps.getElement().getAbsoluteLeft()*(-1);
			moveStepLength = stepsMap.get(toStep).getElement().getOffsetLeft()-currentStepLeft;
			
			if(moveSelectLength != 0)
				run(duration);
		}
	}
	
	private final UnorderedListWidget buttons;
	private final UnorderedListWidget buttonsBg;
	private final UnorderedListWidget steps;
	private final ClientResource resource;	
	private final Map<Step, ListItemWidget> buttonsMap;
	private final Map<Step, ListItemWidget> stepsMap;
	private final FlowPanel selectedButton;
	private final StepChangingAnimation animation;
	
	private int displayWidth;
	private Step currentStep;
	
	@Inject
	public LobbyView(ClientResource resource, ToweeConstants constants) {
		this.resource = resource;
		this.buttons = new UnorderedListWidget();
		this.steps = new UnorderedListWidget();
		this.buttonsBg = new UnorderedListWidget();
		this.buttonsMap = new HashMap<Step, ListItemWidget>();
		this.stepsMap = new HashMap<Step, ListItemWidget>();
		this.animation = new StepChangingAnimation();
		
		// For creating steps container with width of client
		Window.addResizeHandler(this);
		displayWidth = Window.getClientWidth();
		steps.setWidth( (displayWidth*5) + "px" );
		
		// Create buttons
		createButton(Step.NICKNAME, constants.hello()+"!");
		createSeparator();
		createButton(Step.PROFILE, constants.about_me());
		createSeparator();
		createButton(Step.GROUPS, constants.groups());
		createSeparator();
		createButton(Step.CONTACTS, constants.people());
		createSeparator();
		createButton(Step.HELP, constants.tips_and_triks());
		
		// Set lobby buttons
		setStyleName(resource.css().lobby());
		buttonsBg.getElement().getStyle().setZIndex(100);
		buttons.getElement().getStyle().setZIndex(102);
		buttons.setStyleName(resource.css().lobbyButtons());
		buttonsBg.setStyleName(resource.css().lobbyButtons());
		add(buttonsBg);
		add(buttons);
		
		// Create selected shower widget
		selectedButton = new FlowPanel();
		selectedButton.setStyleName(resource.css().lobbySelectedButton());
		selectedButton.getElement().getStyle().setZIndex(101);
		FlowPanel triangle = new FlowPanel();
		triangle.setStyleName(resource.css().lobbySelectedButtonTriangle());
		selectedButton.add(triangle);
		add(selectedButton);
		
		// Set lobby steps
		steps.setStyleName(resource.css().lobbySteps());
		add(steps);
	}
	
	private void createButton(Step step, String name) {
		ListItemWidget button = new ListItemWidget(name);
		button.setStyleName(resource.css().lobbyButton());
		buttonsMap.put(step, button);
		buttons.add(button);
		
		button = new ListItemWidget();
		button.setStyleName(resource.css().lobbyButtonBackground());
		buttonsBg.add(button);
	}
	
	private void createSeparator() {
		ListItemWidget button = new ListItemWidget();
		button.setStyleName(resource.css().lobbyButtonsSeparator());
		buttonsBg.add(button);
	}
	
	@Override
	public HasClickHandlers getNicknameChanger() {
		return buttonsMap.get(Step.NICKNAME);
	}

	@Override
	public HasClickHandlers getProfileChanger() {
		return buttonsMap.get(Step.PROFILE);
	}

	@Override
	public HasClickHandlers getGroupsChanger() {
		return buttonsMap.get(Step.GROUPS);
	}

	@Override
	public HasClickHandlers getContactsChanger() {
		return buttonsMap.get(Step.CONTACTS);
	}

	@Override
	public HasClickHandlers getHelpChanger() {
		return buttonsMap.get(Step.HELP);
	}

	@Override
	public HasWidgets getContainerForNextStep(Step step) {
		ListItemWidget stepItem = new ListItemWidget();
		stepItem.setStyleName(resource.css().lobbyStep());
		stepItem.setWidth(displayWidth + "px");
		stepsMap.put(step, stepItem);
		steps.add(stepItem);
		
		FlowPanel container = new FlowPanel();
		container.setStyleName(resource.css().lobbyStepContainer());
		stepItem.add(container);
		
		return container;
	}

	@Override
	public void selectStep(Step stepType) {
		animation.run(360, stepType);
		currentStep = stepType;
	}

	@Override
	public void onResize(ResizeEvent event) {
		displayWidth = event.getWidth();
		steps.setWidth( (displayWidth*5) + "px" );
		
		for(ListItemWidget step : stepsMap.values())
			step.setWidth(displayWidth + "px");
				
		steps.getElement().getStyle().setProperty("left", stepsMap.get(currentStep).getElement().getOffsetLeft()*(-1)+"px");
	}

}